#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

#include <QSerialPort>
#include <QSerialPortInfo>

#include <QLabel>

#include "sundry.h"

#include "send_single_area.h"
#include "send_multiple_area.h"

#include <QTimer>

#include <windows.h>
#include <dbt.h> // Device Broadcast Header


QT_BEGIN_NAMESPACE
namespace Ui
{
    class MainWindow;
}
QT_END_NAMESPACE

enum SendOptions
{
    singleItem,
    multipleItem
};


class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget* parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow* ui;

private:
    QSerialPort* serialPort;//串口对象
    /**
     * @brief 记录当前选择的串口的信息
     */
    QSerialPortInfo portInfo;
    /**
     * @brief 根据当前选择尝试打开串口
     */
    void openSerialPort(void);
    /**
     * @brief 根据当前选择关闭串口
     */
    void closeSerialPort(void);

    /**
     * @brief 记录当前所有可用串口信息
     * @note ComBox的查找的比较应该是按字节比较，似乎会误判
     */
    QList<QSerialPortInfo> allPortInfo;


private:
    /**
     * @brief 刷新下拉框串口列表
     */
    void refreshComboBox_Port(void);

private:
    EncodingEnum localEncoding=EncodingEnum::UTF8; // 本机编码

    /*状态栏上的标签*/
private:
    QLabel* label_localEncoding = nullptr; // 本机编码标签
    QLabel* label_portInfo=nullptr;//串口是否打开

private:
    /**
     * @brief 设备通知注册
     * @note 只有 Windows 上能用！！移植时注意
     * @note 经测试不调用此函数 nativeEvent 也可以正常使用
     */
    void registerForDeviceNotifications(void);

protected:
    /**
     * @brief nativeEvent
     * @param eventType
     * @param message
     * @param result
     * @return
     * @note 内部调用 Windows 函数，移植时注意
     */
    bool nativeEvent(const QByteArray &eventType, void *message, qintptr  *result) override;


private:
    /**
     * @brief 打开或关闭开关
     */
    void switchToggle(void);

private:
    SendSingleArea* singleArea;//单项发送区
    SendMultipleArea* multipleArea;//多项发送区
    /**
     * @brief 切换发送区
     * @param index comboBox的索引
     */
    void sendAreaChange(int index);



private:
    /**
     * @brief 接收到的数据缓冲区
     */
    QByteArray receiveBuffer;

    /**
     * @brief 将接收到的数据保存到文件
     */
    void saveReceivedDataToFile(void);

private:
    /**
     * @brief 接收数据
     * @note 根据选项进行展示
     */
    void receiveData(void);

    /**
     * @brief 发送数据
     * @param dataString 要发送的字符串
     * @note 根据选项进行发送
     */
    void sendData(QString dataString);
public:
    /**
     * @brief 根据串口打开情况设置一些组件是否启用
     * @param checked
     */
    void setSomeComponents(bool checked);

private:
    QTimer* debounceTimer=nullptr;//防抖
signals:
    /**
     * @brief 串口打开情况
     * @param state 状态 true 已经打开 false 已经关闭
     * @note Qt信号
     */
    void portStateChange(bool state);

    /**
     * @brief 单项发送区自动发送
     * @param checked 开启或关闭
     * @param cycle 周期 毫秒
     */
    void singleAutoSend(bool checked, int cycle);

    /**
     * @brief 多项发送区开启自动发送
     * @param checked 开启或关闭
     * @param cycle 周期 毫秒
     */
    void multipleAutoSend(bool checked, int cycle);


};
#endif // MAINWINDOW_H
